home *** CD-ROM | disk | FTP | other *** search
- /*
- File: uflat.c
- */
- #include <strings.h>
- #include <stdio.h>
- #include <tmc.h>
- #include <cvr.h>
- #include "uflatconst.h"
- #include "tmcode.h"
- #include "utils.h"
-
- /* command line flags */
- static int showorig = TRUE;
- static int symtabtr = FALSE;
- static int anptr = FALSE;
- static int stat = FALSE;
-
- /* common variables */
- #define infile stdin
- #define outfile stdout
-
- FILE *tracestream = stderr;
-
- /* Name of definition to be monitored */
- def thedef;
- def_list new_defs; /* remaining atoms, basetypes and thedef */
-
- /*
- Table of debugging flags plus associated information.
- Table is ended by an entry with flagchar '\0'
- */
- static dbflag flagtab[] =
- {{ 'g', &anptr, "trace lambda removal generation" },
- { 's', &stat, "statistics" },
- { 't', &symtabtr, "symbol table tracing" },
- { '\0', (int *)0, "" },
- };
-
- /* Given a symbol 's', search the context for a definition with
- * that name, and return a pointer to it.
- */
- static ctx_list context;
-
- static def find_def (s)
- symbol s;
- { register unsigned int cix;
- register unsigned int dix;
-
- for (cix = 0; cix < context -> sz; cix++)
- { register def_list l = context -> arr[cix] -> defs;
- for (dix = 0; dix < l -> sz; dix++)
- { register def d = l -> arr[dix];
- switch (d -> tag)
- { case TAGDefAtom:
- if (d -> DefAtom.atnm == s) return (d);
- break;
-
- case TAGDefBasetype:
- if (d -> DefBasetype.basename == s) return (d);
- break;
-
- case TAGDefVal:
- if (d -> DefVal.valnm == s) return (d);
- break;
-
- case TAGDefTyp:
- if (d -> DefTyp.typnm == s) return (d);
- break;
-
- case TAGDefCon:
- break;
-
- default:
- badtag (d -> tag);
- };
- };
- }
- return (defNIL);
- };
-
- /* Check if symbol 'nm' occurs in formcon 'fc' */
- int occurs_in (nm, fc)
- symbol nm;
- formcon fc;
- { switch (fc -> tag)
- { case TAGFCSym:
- if (fc -> FCSym.sym == nm) return (1);
- break;
- case TAGFCList:
- { register int ix;
- register formcon_list fcs = fc -> FCList.l;
- for (ix = 0; ix < fcs -> sz; ix++)
- if (occurs_in (nm, fcs -> arr[ix])) return (1);
- };
- break;
- default:
- badtag (fc -> tag);
- break;
- };
- return (0);
- };
-
- /* Given a symbol 'nm', a value 'sv' and a value 'v', return a copy
- * of 'v' with all occurences of 'nm' replaced by a copy of 'sv'.
- */
- val_list subs_val_list ();
- val subs_val (nm, sv, v)
- symbol nm;
- val sv;
- val v;
- { switch (v -> tag)
- { case TAGVSym:
- if (v -> VSym.sym == nm)
- { return (rdup_val (sv));
- }
- else return (rdup_val (v));
-
- case TAGVLambda:
- if (!(occurs_in (nm, v -> VLambda.lpar)))
- { return (new_VLambda (rdup_formcon (v -> VLambda.lpar),
- subs_val (nm, sv, v -> VLambda.lval)));
- }
- else return (rdup_val (v));
-
- case TAGVSigma:
- case TAGVSyn:
- case TAGVAppset:
- { fprintf (stderr, "Only directional descriptions allowed\n");
- exit (1);
- };
-
- case TAGVApply:
- return (new_VApply (subs_val (nm, sv, v -> VApply.aval),
- subs_val (nm, sv, v -> VApply.apar)));
-
- case TAGVWhere:
- { def d;
- def_list dl;
- def_list nl;
- register unsigned int ix;
-
- dl = v -> VWhere.wdefs;
- if ((dl == def_listNIL) || (dl -> sz == 0))
- return (subs_val (nm, sv, v -> VWhere.wval));
-
- nl = new_def_list ();
- room_def_list (nl, dl -> sz);
- nl -> sz = dl -> sz;
- for (ix=0; ix < dl -> sz; ix++)
- { d = dl -> arr[ix];
- if (d -> tag != TAGDefCon)
- { nl -> arr[ix] = rdup_def (d);
- }
- else
- nl -> arr[ix] = new_DefCon
- (rdup_orig (d -> DefCon.conorig),
- subs_val (nm, sv, d -> DefCon.defcon),
- subs_val (nm, sv, d -> DefCon.conas));
- };
- return (new_VWhere (nl,
- subs_val (nm, sv, v -> VWhere.wval)));
- };
-
- case TAGVList:
- return (new_VList (subs_val_list (nm, sv, v -> VList.l)));
-
- case TAGVAtom:
- return (new_VAtom (rdup_orig (v -> VAtom.atorig),
- rdup_symbol (v -> VAtom.atnm),
- rdup_parval_list (v -> VAtom.atvpar),
- subs_val (nm, sv, v -> VAtom.atcpar)));
- default:
- badtag (v -> tag);
- };
- };
-
- /* Given a symbol 'nm', a value 'sv' and a value list 'vl', return a copy
- * of 'vl' with all occurences of 'nm' replaced by a copy of 'sv'.
- */
- static val_list subs_val_list (nm, sv, vl)
- symbol nm;
- val sv;
- val_list vl;
- { register unsigned int ix;
- val_list nl = new_val_list ();
- if (vl == val_listNIL) return (nl);
- room_val_list (nl, vl -> sz);
- nl -> sz = vl -> sz;
-
- for (ix=0; ix < vl -> sz; ix++)
- nl -> arr[ix] = subs_val (nm, sv, vl -> arr[ix]);
- return (nl);
- };
-
- /* Copy all global basetype and atom definitions */
- static copy_basenamedefs (new, old)
- def_list new, old;
- { register int ix;
- register def d;
- for (ix = 0; ix < old -> sz; ix++)
- { d = old -> arr[ix];
- switch (d -> tag)
- { case TAGDefAtom:
- app_def_list (new, rdup_def (d));
- break;
- case TAGDefBasetype:
- app_def_list (new, rdup_def (d));
- break;
- case TAGDefVal:
- break;
- case TAGDefCon:
- case TAGDefTyp:
- default:
- badtag (d -> tag);
- break;
- };
- };
- };
-
- /*
- Expand thedef
- */
- static val expand_val ();
- static val_list expand_val_list ();
- static def expand_thedef (d)
- def d;
- { val newrhs;
- val rhs = d -> DefVal.valas;
- if (rhs -> tag != TAGVLambda)
- { fprintf (stderr, "Lambda abstractor expected\n");
- exit (1);
- };
- newrhs = new_VLambda (rdup_formcon (rhs -> VLambda.lpar),
- expand_val (rhs -> VLambda.lval));
- return (new_DefVal (rdup_orig (d -> DefVal.valorig),
- rdup_symbol (d -> DefVal.valnm),
- rdup_typ (d -> DefVal.valtyp), newrhs));
- };
-
- static val formcon_to_val (fc)
- formcon fc;
- { switch (fc -> tag)
- { case TAGFCSym:
- return (new_VSym (rdup_orig (thedef -> DefVal.valorig),
- rdup_symbol (fc -> FCSym.sym)));
- case TAGFCList:
- { val_list vl = new_val_list ();
- formcon_list fcl = fc -> FCList.l;
- if ((fcl != formcon_listNIL) && (fcl -> sz != 0))
- { register int ix;
- room_val_list (vl, fcl -> sz);
- vl -> sz = fcl -> sz;
- for (ix=0; ix < fcl -> sz; ix++)
- vl -> arr[ix] = formcon_to_val (fcl -> arr[ix]);
- };
- return (new_VList (vl));
- };
- default: badtag (fc -> tag);
- };
- };
-
- static val try_subst (expr, fc, arg)
- val expr;
- formcon fc;
- val arg;
- { switch (fc -> tag)
- { case TAGFCSym:
- return (subs_val (fc -> FCSym.sym, arg, expr));
- case TAGFCList:
- { formcon_list fcl = fc -> FCList.l;
- def_list dl;
- if ((fcl == formcon_listNIL) || (fcl -> sz == 0))
- return (rdup_val (expr));
- if ((arg -> tag == TAGVList) &&
- (arg -> VList.l -> sz == fcl -> sz))
- { /* formal and actuals match... */
- register int ix;
- val new = rdup_val (expr);
- for (ix = 0; ix < fcl -> sz; ix++)
- { val prev = new;
- new = try_subst (prev, fcl -> arr[ix],
- arg -> VList.l -> arr[ix]);
- rfre_val (prev);
- };
- return (new);
- };
- dl = new_def_list ();
- app_def_list (dl, new_DefCon
- (rdup_orig (thedef -> DefVal.valorig),
- formcon_to_val (fc),
- rdup_val (arg)));
- return (new_VWhere (dl, rdup_val (expr)));
- };
- default: badtag (fc -> tag);
- };
- };
-
- static val beta_reduce (lab, arg)
- val lab,arg;
- { val expr = rdup_val (lab -> VLambda.lval);
- val mexpr = try_subst (expr, lab -> VLambda.lpar, arg);
- val texpr = expand_val (mexpr);
- rfre_val (expr);
- rfre_val (mexpr);
- return (texpr);
- };
-
- static val expand_application (v)
- val v;
- { val appsys = v -> VApply.aval;
- val args = v -> VApply.apar;
- switch (appsys -> tag)
- { case TAGVSym:
- { def found = find_def (appsys -> VSym.sym);
- if (found == defNIL)
- { fprintf (stderr, "Definition not found\n");
- exit (1);
- };
- if ((found -> tag != TAGDefVal) ||
- (found -> DefVal.valas -> tag != TAGVLambda))
- { fprintf (stderr, "Wrong definition found\n");
- exit (1);
- };
- return (beta_reduce (found -> DefVal.valas, args));
- };
- case TAGVLambda:
- return (beta_reduce (appsys, args));
- case TAGVSigma:
- { fprintf (stderr, "Only directional systems allowed\n");
- exit (1);
- };
- default: badtag (appsys -> tag);
- };
- };
-
- static int def_may_be_deleted (d)
- def d;
- { val lhs = d -> DefCon.defcon;
- val rhs = d -> DefCon.conas;
- if (lhs -> tag == TAGVList)
- { val_list vl = lhs -> VList.l;
- if (vl -> sz == 0) return (1);
- };
- if (rhs -> tag == TAGVList)
- { val_list vl = rhs -> VList.l;
- if (vl -> sz == 0) return (1);
- };
- return (0);
- };
-
- static val expand_wheres (v)
- val v;
- { def_list wdefs = v -> VWhere.wdefs;
- def_list ndefs;
- val newval;
- register int ix;
- if ((wdefs == def_listNIL) || (wdefs -> sz == 0))
- return (expand_val (v -> VWhere.wval));
- ins_ctx_list (context, 0, new_ctx (rdup_def_list (wdefs)));
- ndefs = new_def_list ();
- for (ix=0; ix < wdefs -> sz; ix++)
- { def d = wdefs -> arr[ix];
- switch (d -> tag)
- { case TAGDefBasetype:
- case TAGDefAtom:
- app_def_list (new_defs, rdup_def (d));
- break;
- case TAGDefVal:
- break;
- case TAGDefCon:
- if (!def_may_be_deleted (d))
- app_def_list (ndefs, new_DefCon
- (rdup_orig (d -> DefCon.conorig),
- rdup_val (d -> DefCon.defcon),
- expand_val (d -> DefCon.conas)));
- break;
- default:
- badtag (d -> tag);
- };
- };
- if (ndefs -> sz == 0)
- { newval = expand_val (v -> VWhere.wval);
- rfre_def_list (ndefs);
- }
- else
- newval = new_VWhere (ndefs, expand_val (v -> VWhere.wval));
- del_ctx_list (context, 0);
- return (newval);
- };
-
- static val expand_val (v)
- val v;
- { switch (v -> tag)
- { case TAGVSym:
- return (rdup_val (v));
- case TAGVLambda:
- { fprintf (stderr, "All abstractors should have vanished\n");
- exit (1);
- };
- case TAGVApply:
- return (expand_application (v));
- case TAGVWhere:
- return (expand_wheres (v));
- case TAGVList:
- return (new_VList (expand_val_list (v -> VList.l)));
- case TAGVAtom:
- return (new_VAtom (rdup_orig (v -> VAtom.atorig),
- rdup_symbol (v -> VAtom.atnm),
- rdup_parval_list (v -> VAtom.atvpar),
- expand_val (v -> VAtom.atcpar)));
- case TAGVAppset:
- case TAGVSigma:
- case TAGVSyn:
- { fprintf (stderr, "Only directional systems allowed\n");
- exit (1);
- };
- default:
- badtag (v -> tag);
- };
- };
-
- static val_list expand_val_list (vl)
- val_list vl;
- { register int ix;
- val_list new = new_val_list ();
- for (ix = 0; ix < vl -> sz; ix++)
- app_val_list (new, expand_val (vl -> arr[ix]));
- return (new);
- };
-
- /* Print usage of this program */
- static void usage (f)
- FILE *f;
- { fprintf (f, "Usage: gen [-d<debugging flags>]\n");
- helpdbflags (f, flagtab);
- };
-
- /* scan arguments and options */
- static void scanargs (argc, argv)
- int argc;
- char *argv[];
- { int op;
- argv++;
- argc--;
- while (argc>0)
- { if (argv[0][0] != '-')
- { fprintf (stderr, "too many arguments\n");
- usage (stderr);
- exit (1);
- };
- op = argv[0][1];
- switch (op)
- { case 'd': setdbflags (&argv[0][2], flagtab, TRUE);
- break;
-
- case 'h':
- case 'H': usage (stdout);
- exit (0);
-
- case 'o': showorig = FALSE;
- break;
-
- default: usage (stderr);
- exit (1);
- };
- argc--;
- argv++;
- };
- };
-
- static def find_thedef (dl)
- def_list dl;
- { register int ix;
- register def d;
- register def mdef = defNIL;
- for (ix = 0; ix < dl -> sz; ix++)
- { d = dl -> arr[ix];
- if (d -> tag == TAGDefVal) mdef = d;
- };
- if (mdef == defNIL)
- { fprintf ("No expandible definition found\n");
- exit (1);
- };
- return (mdef);
- };
-
- main (argc, argv)
- int argc;
- char *argv [];
- { def_list all_defs;
- initsymbol ();
- scanargs (argc, argv);
- tmlineno = 1;
- fprintf (stderr, "uflat: loading...\n");
- if (fscan_def_list (infile, &all_defs))
- { fprintf (stderr, "Read error: (%d): %s\n", tmlineno, tmerrmsg);
- exit (1);
- };
- thedef = find_thedef (all_defs);
- new_defs = new_def_list ();
- context = new_ctx_list ();
- ins_ctx_list (context, 0, new_ctx (rdup_def_list (all_defs)));
- fprintf (stderr, "uflat: expanding...\n");
- copy_basenamedefs (new_defs, all_defs);
- app_def_list (new_defs, expand_thedef (thedef));
- rfre_ctx_list (context);
- fprint_def_list (outfile, new_defs);
- if (stat)
- { rfre_def_list (new_defs);
- rfre_def_list (all_defs);
- flushsymbol ();
- stat_ds (stderr);
- stat_string (stderr);
- };
- }
-